package com.github.beansoft.jadx.util;

import jadx.api.ICodeInfo;
import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import jadx.core.Jadx;
import jadx.core.ProcessClass;
import jadx.core.codegen.CodeGen;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.visitors.IDexTreeVisitor;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.List;

public class Dex2JavaUtil {
  private static RootNode getClassNodeFromFile(File file) {
    JadxDecompiler d = null;
    try {
      JadxArgs args = new JadxArgs();
      args.setShowInconsistentCode(true);
      args.setThreadsCount(1);
      args.setSkipResources(true);
      args.setInputFiles(Collections.singletonList(file));
      d = new JadxDecompiler(args);
      d.load();
    } catch (Exception e) {
      e.printStackTrace();
    }
    RootNode root = d.getRoot();

    return root;
  }

  private static ClassNode getClassNodeFromFile(File file, String clsName) {
    RootNode root = getClassNodeFromFile(file);
    ClassNode cls = root.resolveClass(clsName);
    return cls;
  }
  
  protected static void decompile(JadxDecompiler jadx, ClassNode cls) {
    List<IDexTreeVisitor> passes = Jadx.getPassesList(jadx.getArgs());
    ICodeInfo codeInfo = ProcessClass.generateCode(cls);
  }

  public static String convertAll2Java(File dexFile) {
    RootNode root = getClassNodeFromFile(dexFile);
    List<ClassNode> classNodes = root.getClassesWithoutInner();
    StringBuilder out = new StringBuilder();
    if(classNodes != null) {
      for(ClassNode clazz : classNodes) {
        String code = clazz.getCode().toString();
        out.append(code).append("\n\n");
      }
    }
    return out.toString();
  }

  public static String convertAll2Java(byte[] classesDex) {
    try {
      File dexFile =Files.createTempFile("jadx-gui-idea", ".dex").toFile();
      com.intellij.openapi.util.io.FileUtil.writeToFile(dexFile, classesDex);
      return convertAll2Java(dexFile);
    } catch (IOException e1) {
      e1.printStackTrace();
      return "convert failed";
    }
  }

  public static String convert2Java(byte[] classesDex, String nodeClassName) {
    try {
      File dexFile = new File("./classes.dex");
      com.intellij.openapi.util.io.FileUtil.writeToFile(dexFile, classesDex);
      ClassNode cls = getClassNodeFromFile(dexFile, nodeClassName);
      return cls.getCode().toString();
    } catch (IOException e1) {
      e1.printStackTrace();
      return "convert failed";
    } 
  }

  public static void main(String[] args) {
    try {
      File dexFile = new File("./data/classes.dex");
      ClassNode cls = getClassNodeFromFile(dexFile, "com.huimin.printer.App");
//      String code = cls.getCode().toString();
      System.out.println(convertAll2Java(dexFile));
    } catch (Exception e1) {
      e1.printStackTrace();
    }
  }
}
